const callbacks = []; // 存储 flushSchedularQueue 函数

let waiting = false; // 防抖原理，防止调用多次标记，开启多个 setTimeout

function flushCallback() {
  // console.log(callbacks)
  callbacks.forEach(cb => cb());
  waiting = false;
}

function isNative(v) {
  return v.toString().indexOf("[native code]") !== -1;
}

let timeFunc = null;
if (typeof Promise !== 'undefined' && isNative(Promise)) {
  const p = Promise.resolve();
  timeFunc = () => {
    p.then(flushCallback);
  }
} else if (typeof MutationObserver !== 'undefined') {
  const observer = new MutationObserver(flushCallback);
  const textNode = document.createTextNode(1);
  // 检测是否有更新，如果有更新，就自动调用 flushCallback
  observer.observe(textNode, { characterData: true });
  timeFunc = () => {
    textNode.textContent = 2;
  }
} else if (typeof setImmeditate !== 'undefined') {
  timeFunc = () => {
    setImmeditate(flushCallback);
  }
} else {
  timeFunc = () => {
    setTimeout(flushCallback, 0);
  }
}

export function nextTick(callback) {
  callbacks.push(callback);
  if (!waiting) {
    // $nextTick => Promise/mutationObserver/setImmediate/setTimeout
    // if (typeof Promise !== "undefined" && Promise.toString().indexOf("[native code]") !== -1) {
    //   Promise.resolve().then(flushCallback);
    // } else {
    //   setTimeout(flushCallback, 0);
    // }
    timeFunc();
    waiting = true;
  }
}

// 异步任务：宏任务，微任务
// 宏任务：setTimeout，setImmediate
// 微任务：promise.then, mutationObserver

// vue 期望尽快更新，最好使用微任务